// 1.用递归的方式实现  一个对象覆盖掉另一个对象的属性和值
export const deepCopy = (A, B) => {
    // let A = { a: 1, b: 2 }; let B = { c: 3, b: 5, d: { f: 1, g: 2 } }
    // 首先判断B是否是一个对象
    if (Object.prototype.toString.call(B) !== '[object Object]') {
        return B;
    } else {
        // 1. B是一个对象类型
        // 2. 对B进行遍历操作取出B的属性和属性值
        for (let attr in B) {
            var a = {}                            //  1.    C ==3                     // 2. b==5                    // 3. d=={}
            // 判断A中是否存在这个属性
            if (A[attr]) {                        //  1.    a={}   B[c]==3    A.C==3  // 2. a==2   B[b]==5  A.b==5  // 3. a={}, A[d]=for(){1.a={},f==1, a.f=1,a.g=2  return a }
                a = A[attr]
            }                                     //  A[d]=a;  return A
            A[attr] = deepCopy(a, B[attr])
        }
        return A
    }
}

// 2.如何在普通的js文件使用 import模块导入语法
export const importKnack = [
    // "直接使用import会报错 cannot use import....",
    "1. 在script标签中 加上module type类型如 <script type='module'></script>",
    "2. 再次启动，此时还是会报错，提示 Acc...跨域问题，需要全局安装  http - server",
    "3. 再次启动就好了，http - server会启动失败，通过 Windows Pow... A就好了  去学习吧"
]

// 3.检测数据类型的方法
export const detectionData = [
    "1.检测基本数据类型 typeof, 对于复杂数据类型检测模糊function object",
    "2.instanceof二元运算符 arr instanceof Array true||false 不能用来判断字符串和数字",
    "3.constructor默认指向实例的构造函数，不一定准确因为可以修改，变更",
    "4.Object.prototype.toString.call判断某个对象属于哪一种内置类型 [object Object] [object Function]"
]

// 4.vue中$nextTick()和$set方法介绍
export const vueMethods = [
    "vue中mounted不会承诺所有的子组件一起被挂载，dom渲染和数据加载是异步的，让dom跟着数据发生改变需要$nexttick,mounted操作dom基本不会出现问题",
    "$set是双向数据绑定object.defineProperty()对数据进行添加seter，geter函数，动态添加不会有这个方法所以视图不会更新，通过$set方法就会有seter，geter"
]

// 5.vue中vue.prototype方法的介绍
export const vuePrototype = () => {
    return `Vue.prototype.$appName='uniapp_cj'`
    // 1.所有实例都能够通过 this.$appName进行访问这个数据,常量不能被修改
    // 2.引用类型可以被修改 $obj={appName:"uniapp_cj"}
    // $是用来区分私有化组件数据和原型上的数据
}

// 6.防抖和节流 节流是防止短时间内多次做事，防抖是一直做事隔段时间开始做   ----防抖
export const debounce = (fn, delay) => {
    let timer = null;
    return function () {
        if (timer) {
            clearTimeout(timer)
            timer = setTimeout(function () {
                fn()
            }, delay)
        } else {
            timer = setTimeout(function () {
                fn()
            }, delay)
        }
    }
}

// 7.节流
export const throttle = (fn, delay) => {
    // 事件一直在触发,延迟后执行
    let valid = true;
    return function () {
        if (valid) {
            valid = false
            setTimeout(function () {
                fn()
                valid = true
            }, delay)
        } else {
            return false
        }
    }

}

// 8.uniapp 分包和小程序之间的跳转
export const myPackagesC = [
    // 1.分包可以使小程序体积减小  小程序分主包 和 分包
    // 2.优先考虑 主页用到的组件页面放到主包里面
    // 3.根据tabbar 其他模块分别进行分包
    // 4.分包不能引入主包资源  相应的限制看官网
    {
        "root": "myPackageC",//包名称
        "pages": [
            {
                "path": "pages/newWeixinApp",//包内路径
                "style": {
                    "navigationBarTitleText": "加油"
                }
            },
        ]
    },
    {
        // 1.相应的跳转接口 官网
        // 2.可以传参数  跳转指定的页面
        // 3.字符串去除两边的留白 trim() 今天被坑坏了
    }
]

// 9.马上更新小程序唤起第三方app 例如高德地图
export const openApp=[
    "uni.openLocation"//在微信小程序中直接打开第三方的应用
]

// 10.对style属性scoped的理解
export const scoped = [
    // 作用: 保证css样式只作用于当前组件，不会影响其他任何地方的样式
    // 本质：设置 scoped 后，当前组件中的所有元素都会被添加一个 data-v- 的属性，所有设置的css样式都会添加该属性选择器
    // 1.父组件和子组件都添加scoped属性时   <父子组件样式都不受影响 >
    // 2.父组件设置scoped,子组件不设置scoped，<父组件样式不会影响到子组件,但是子组件的css样式权重高于父组件则会影响父组件>
    // 3.父组件不设置scoped,子组件设置scoped <子组件不会影响到父组件，但是父组件权重高会影响子组件样式>
]


// 11.js为什么是单线程的
export const jsTheory = 'js创建之初就是为了操作dom的,如果它不是单线程的会会出现一些问题····event loop'

// 12.js继承的几种方式 
export const Methods=['1.原型的继承','2.构造函数的继承','3.组合继承','4.寄生组合继承','5.class继承']